#include "cc_time.h"
#include "cc_common.h"
#include <windows.h>

int __cdecl cc_init_time(
	void
);

static char * asctimeBuf[ASCTIME_BUFSIZE];
static const char weekdaysNames[] = "SunMonTueWedThuFriSat";
static const char monthsNames[] = "JanFebMarAprMayJunJulAugSepOctNovDec";

static unsigned __int64 cc_start_ticks;

_CRTALLOC(".CRT$XIC") static _PIFV pinit = cc_init_time;

int __cdecl cc_init_time(
	void
	)
{
	cc_FT ft;

	GetSystemTimeAsFileTime(&ft);
	cc_start_ticks = ft.ft_scalar;
	return 0;
}

// store the tm info(day, hour, minute, sec) from int to char, 
// their length is equal to 2.
static void __cdecl cc_store_tm(
	int num,
	char **store
	)
{
	char *temp = *store;
	if(num < 10)
	{
		*temp++ = '0';
		*temp++ = num + '0';
	}
	else
	{
		*temp++ = num / 10 + '0';
		*temp++ = num % 10 + '0';
	}
	(*store) += 2;
}

char * __cdecl cc_asctime( 
	const cc_tm *tm 
	)
{
	char *temp = asctimeBuf;
	char *year;
	int i;

	// construct the str like "Wed Jan 02 02:03:55 2011\n\0"
	for(i = 0; i < 3; ++i)			// weekday
		*temp++ = weekdaysNames[i + tm->wday * 3];

	*temp++ = ' ';
	for(i = 0; i < 3; ++i)			// month
		*temp++ = monthsNames[i + tm->month * 3];

	*temp++ = ' ';
	cc_store_tm(tm->day, &temp);	// day

	*temp++ = ' ';
	cc_store_tm(tm->hour, &temp);	// hour

	*temp++ = ':';
	cc_store_tm(tm->min, &temp);	// minute

	*temp++ = ':';
	cc_store_tm(tm->sec, &temp);	// second

	*temp++ = ' ';
	year = cc_itoa(tm->year + 1900);
	if(!year)
		return NULL;

	cc_strncpy(temp, year, 4);	// commonly, the year str's length is 4.
	temp += 4;		
	*temp++ = '\n';
						// don't need to set the last char '\0', because by default the  asctimeBuf str is set by '\0',
	cc_free(year);
	return asctimeBuf;
}

cc_time_t __cdecl cc_time( 
	cc_time_t *tm
	)
{
	cc_FT ft;
	cc_time_t tt;

	GetSystemTimeAsFileTime(&ft.ft_struct);
	tt = (ft.ft_scalar - EPOCH_BIAS) / 10000000i64;
	if(tm)
		*tm = tt;

	return tt;
}

double __cdecl cc_difftime( 
	cc_time_t t1, 
	cc_time_t t2 
	)
{
	return (t1 - t2);
}

cc_clock_t __cdecl cc_clock( 
	void 
	)
{
	unsigned __int64 currClk;
	cc_FT ft;

	GetSystemTimeAsFileTime(&ft);
	ft.ft_scalar -= cc_start_ticks;

	return (cc_clock_t)(ft.ft_scalar / 10000);
}

/*
struct cc_tm * __cdecl cc_localtime( 
	const time_t *t
	)
{

}
*/
